﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Puddy.Resources;
using Puddy.ViewModels;
using System.Windows.Media.Imaging;
using Puddy.Utils;
using System.Diagnostics;
using System.Threading;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
using Puddy.UserControls;
using Puddy.Models;
using System.Windows.Resources;
using System.IO.IsolatedStorage;
using Windows.Storage;
using Windows.Devices.Geolocation;



namespace Puddy
{
    public partial class MainPage : PhoneApplicationPage
    {
        BackgroundWorker backroungWorker;
        Popup myPopup;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            //avoid case back from alarm page
            if (!App.ViewModel.IsLocationListDataLoaded)
            {
                myPopup = new Popup() { IsOpen = true, Child = new AnimatedSplashScreen() };
                backroungWorker = new BackgroundWorker();
                RunBackgroundWorker();



                CopyToIsolatedStorage();

                // Set the data context of the LongListSelector control to the sample data
                
            }

            DataContext = App.ViewModel.LocationList;

            MainLongListSelector.UpdateLayout();

            App.MainPage = this;

        }

        private void RunBackgroundWorker()
        {
            backroungWorker.DoWork += ((s, args) =>
            {
                Thread.Sleep(4000);
            });

            backroungWorker.RunWorkerCompleted += ((s, args) =>
            {
                this.Dispatcher.BeginInvoke(() =>
                {
                    this.myPopup.IsOpen = false;
                    this.UpdateLayout();

                    App.initLocation();
                    //fixed bug show message before splash screen
                    if (App.ViewModel.ListItemStateOn.Count > 0)
                    {
                        App.turnOnTrackLocation();
                    }
                }

                );

                
            });
            backroungWorker.RunWorkerAsync();
        }

        // Load data for the ViewModel Items
        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            if (App.RunningAlarm)
            {
                this.NavigationService.Navigate(new Uri("/AlarmPage.xaml", UriKind.Relative));
            }

            if (App.ShouldShowMessTurnOffLocation)
            {
                App.ShouldShowMessTurnOffLocation = false;
                MessageBox.Show(Constants.MES_TURN_OFF_LOCATION);
                
            }

            if (!App.ViewModel.IsLocationListDataLoaded)
            {
                await App.ViewModel.LoadListLocation();

                

                SettingAlarm setting = await RestoreData.GetSettingAlarm() as SettingAlarm;
                if (setting == null)
                {
                    setting = new SettingAlarm(Constants.KM_TYPE, 2, null);
                    
                }
                App.Setting = setting;
            }

            if (!App.ViewModel.IsSettingAlarmDataLoaded)
            {
                await App.ViewModel.loadListRingTone();



                if (App.Setting.AlarmTonePath != null)
                {
                    foreach (RingToneViewModel ringTone in App.ViewModel.RingToneList)
                    {
                        if (ringTone.Path == App.Setting.AlarmTonePath)
                        {
                            App.CurrentRingTone = ringTone;
                            break;
                        }
                    }
                }
                else
                {
                    if (App.ViewModel.RingToneList.Count > 0)
                    {
                        App.CurrentRingTone = App.ViewModel.RingToneList.ElementAt(0);
                        App.Setting.AlarmTonePath = App.CurrentRingTone.Path;
                    }
                }


            }
            App.CurrentRingTone.IsSelected = true;

            
        }

        protected override void OnBackKeyPress(CancelEventArgs e)
        {
            


            if (App.ViewModel.ListItemStateOn.Count > 0)
            {
                if (MessageBox.Show("The Puddy will not alarm when exited!", "Do you want to exit?", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
                {
                    //Delete Sentences
                    e.Cancel = true;
                    base.OnBackKeyPress(e);
                    return;
                }
            }
            
            Application.Current.Terminate();
            base.OnBackKeyPress(e);
        }

        /// <summary>
        /// Copies the files from the application data to isolated storage.
        /// </summary>
        private async void CopyToIsolatedStorage()
        {
            StorageFolder store = Windows.Storage.ApplicationData.Current.LocalFolder;

            StorageFolder folder = null;

            try
            {
                folder = await store.GetFolderAsync("RingTones");
            }
            catch (System.IO.FileNotFoundException)
            { }

            if (folder == null)
            {
                StorageFolder install = Windows.ApplicationModel.Package.Current.InstalledLocation;
                folder = await install.GetFolderAsync("Assets\\RingTones");

            }

            var ringTones = await folder.GetFilesAsync();

            using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
            {

                foreach (StorageFile f in ringTones)
                {
                    if (!storage.FileExists(f.Name.Replace(" ", "")))
                    {
                        string _filePath = "Assets/RingTones/" + f.Name;
                        StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));

                        using (IsolatedStorageFileStream file = storage.CreateFile(f.Name.Replace(" ", "")))
                        {
                            int chunkSize = 4096;
                            byte[] bytes = new byte[chunkSize];
                            int byteCount;

                            while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
                            {
                                file.Write(bytes, 0, byteCount);
                            }
                        }
                    }
                }

            }
        }

        #region events

        private void btnSelectMusic_Click(object sender, RoutedEventArgs e)
        {
            
           this.NavigationService.Navigate(new Uri("/ToneSelectionPage.xaml", UriKind.Relative));
            
        }    

        private void btnAddLocation_Click(object sender, RoutedEventArgs e)
        {
            this.NavigationService.Navigate(new Uri("/AddLocationPage.xaml", UriKind.Relative));
        }

        private void btnSetting_Click(object sender, RoutedEventArgs e)
        {
            this.NavigationService.Navigate(new Uri("/SettingPage.xaml", UriKind.Relative));
        }

        private  void btnChangeState_Click(object sender, RoutedEventArgs e)
        {
            
            Button b = sender as Button;
            LocationViewModel location = (LocationViewModel)b.Tag;
            if (location != null)
            {
                //LocationViewModel location = App.ViewModel.LocationList.ElementAt(index);
                int state = location.State;

                switch (state)
                {
                    case Constants.ON_STATE:
                        location.State = Constants.OFF_STATE;
                        App.ViewModel.ListItemStateOn.Remove(location);

                        break;
                    case Constants.OFF_STATE:
                        location.State = Constants.ON_STATE;
                        App.ViewModel.ListItemStateOn.Add(location);
                        break;
                    case Constants.DELETE_STATE:
                        App.ViewModel.LocationList.Remove(location);
                        break;
                }

                //Debug.WriteLine("save file -> number location: " + App.ViewModel.LocationList.Count);
                RestoreData.CreateJsonLocationList(App.ViewModel.LocationList);
            }
            else
            {
                
            }

            if (App.ViewModel.ListItemStateOn.Count == 0)
            {                
                 App.turnOffTrackLocation();               
            }
            else if (App.ViewModel.ListItemStateOn.Count == 1)
            {
                App.turnOnTrackLocation();
            }
            else
            {
                App.recheckLocation();
            }

        }


        #endregion



        Point Point_Start;
        Point point_Move;
        

        private void Item_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Point_Start = e.GetPosition((UIElement)sender);
            point_Move = Point_Start;
        }

        private void Item_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {            
            LocationViewModel locationVC = ((Grid)sender).DataContext as LocationViewModel;

            //Because system return point end  wrong --> using point move
            Point newPoint = point_Move;

            if (Point_Start.Y < (newPoint.Y + 20) && Point_Start.Y > (newPoint.Y - 20))
            {
                if (newPoint.X < (Point_Start.X - 20))
                {
                    if (locationVC.State == Constants.ON_STATE)
                    {
                        App.ViewModel.ListItemStateOn.Remove(locationVC);
                    }

                    locationVC.State = Constants.DELETE_STATE;

                    RestoreData.CreateJsonLocationList(App.ViewModel.LocationList);

                }
                else
                {
                    if (newPoint.X > Point_Start.X + 20)
                    {
                        if (locationVC.State == Constants.DELETE_STATE)
                        {
                            locationVC.State = Constants.OFF_STATE;

                            RestoreData.CreateJsonLocationList(App.ViewModel.LocationList);
                        }
                    }
                }
            }

        }

        private void Item_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            point_Move = e.GetPosition((UIElement)sender);
        }

        
    }
}